<?php


namespace WenRuns\Laravel\Cache;


use Illuminate\Redis\Connections\PredisConnection;

/**
 * Class Redis
 * @package WenRuns\Laravel\Cache
 * @method static set($key, $value)
 * @method static get($key, $default = null)
 * @method static del(array|string $key)
 * @method static mset($mkv)
 * @method static mget(Array $keys)
 * @method static setex($key, $expire, $value)
 * @method static setnx($key, $value)
 * @method static getset($key, $default = null)
 * @method static incrby($key, $expire, $value)
 * @method static incr($key, $expire, $value)
 * @method static decrby($key, $expire, $value)
 * @method static decr($key, $expire, $value)
 * @method static exists($key)
 * @method static type($key)
 * @method static append($key, $string)
 * @method static setrange($key, $pos, $replace)
 * @method static substr($key, $pos, $len)
 * @method static setbit($key, $pos, $value)
 * @method static getbit($key, $pos)
 * @method static keys($key)
 * @method static randomkey()
 * @method static rename($name, $new_name)
 * @method static renamenx($name, $new_name)
 * @method static expire($key, $expires)
 * @method static ttl($key)
 * @method static persist($key)
 * @method static dbsize()
 * @method static lpush($key, $value)
 * @method static lpushx($key, $value)
 * @method static rpush($key, $value)
 * @method static rpushx($key, $value)
 * @method static llen($key)
 * @method static lrange($key, $start = 0, $end = -1)
 * @method static lindex($key, $pos)
 * @method static lset($key, $pos, $value)
 * @method static lrem($key, $direction, $string)
 * @method static lpop($key)
 * @method static rpop($key)
 * @method static ltrim($key, $start, $end)
 * @method static flushdb()
 * @method static select($database = 0)
 * @method static disconnect()
 * @method static command($method, array $parameters = [])
 * @method static executeRaw(array $parameters)
 * @method static createSubscription($channels, \Closure $callback, $method = 'subscribe')
 * @method static psubscribe($channels, \Closure $callback)
 * @method static subscribe($channels, \Closure $callback)
 * @method static evalsha($script, $numkeys, ...$arguments)
 * @method static eval($script, $numberOfKeys, ...$arguments)
 * @emthod static transaction(callable $callback = null)
 * @method static pipeline(callable $callback = null)
 * @method static sscan($key, $cursor, $options = [])
 * @method static hscan($key, $cursor, $options = [])
 * @method static zscan($key, $cursor, $options = [])
 * @method static scan($cursor, $options = [])
 * @method static zunionstore($output, $keys, $options = [])
 * @method static zinterstore($output, $keys, $options = [])
 * @method static zrevrangebyscore($key, $min, $max, $options = [])
 * @method static zrangebyscore($key, $min, $max, $options = [])
 * @method static zadd($key, ...$dictionary)
 * @method static spop($key, $count = 1)
 * @method static brpop(...$arguments)
 * @method static blpop(...$arguments)
 * @method static hsetnx($hash, $key, $value)
 * @method static hmset($key, ...$dictionary)
 * @method static hmget($key, ...$dictionary)
 * @method static listen(\Closure $callback)
 */
class Redis
{
    /**
     * @var \Illuminate\Contracts\Foundation\Application|mixed |PredisConnection
     */
    protected $client;

    /**
     * @var
     */
    protected static $instance;


    public function __construct()
    {
        $this->client = app("redis.connection");
    }

    /**
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        // TODO: Implement __call() method.
        return $this->client->$name(...$arguments);
    }


    /**
     * @return static|PredisConnection
     */
    protected static function getInstance()
    {
        if (empty(self::$instance)) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    public static function __callStatic($name, $arguments)
    {
        return self::getInstance()->$name(...$arguments);
    }

    public static function each($key, \Closure $closure, $json = false)
    {
        $i = 0;
        while ($item = self::rpop($key)) {
            if ($json) {
                $item = json_decode($item, true);
            }
            call_user_func($closure, $item, $i);
            $i++;
        }
    }
}
